<?php
/**
 * Cameo Library
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 *
 * @category   Cameo
 * @package    Cameo_SMS
 * @copyright  Copyright (c) 2008 Sylvain Filteau (http://www.cidsphere.com)
 */

/**
 * Cameo_SMS_Gateway_Abstract
 */
require_once('Cameo/SMS/Gateway/Abstract.php');

/**
 * Cameo_SMS_Exception
 */
require_once('Cameo/SMS/Exception.php');

/**
 * Class for creating an SMS message to be sent to a gateway
 *
 * @category   Cameo
 * @package    Cameo_SMS
 * @copyright  Copyright (c) 2008 Sylvain Filteau (http://www.cidsphere.com)
 * 
 * @todo add some static configuration for this class like the default sender name
 */
class Cameo_SMS_Message {
	
	/**
	 * Reference to the gateway that created the message
	 *
	 * @var Cameo_SMS_Gateway_Abstract
	 */
	private $_gateway;
	
	/**
	 * The destination of the message
	 *
	 * @var string
	 */
	private $_to;
	
	/**
	 * The name of the sender.
	 * 
	 * Note that for certain gateway, this name must be registered before sending
	 * a message. (ex: Clickatell)
	 *
	 * @var string
	 */
	private $_from = 'Cameo SMS Sender';
	
	/**
	 * Indicates if the message is in Unicode or not
	 *
	 * @var boolean
	 */
	private $_unicode = false;
	
	/**
	 * Body text of the message
	 *
	 * @var string
	 */
	private $_text;
	
	/**
	 * An ID generated at the message creation
	 *
	 * @var string
	 */
	private $_unique_id;
	
	/**
	 * String that will make the unique id more unique and difficult to predict
	 *
	 * @var string
	 */
	public static $UNIQUE_ID_SALT = 'CAMEO_SMS_SALTER';
	
	/**
	 * Constructor.
	 * 
	 * By default, the message is setted not to be in Unicode. You can set this 
	 * flag while setting the body text with the method setText.
	 *
	 * @param Cameo_SMS_Gateway_Abstract $gateway Reference to the gateway that creates the message
	 * @param array $message_options options for the message
	 * 
	 * @todo Create the message and set all the attributes with the message options
	 */
	public function __construct(array $message_options = array(), Cameo_SMS_Gateway_Abstract $gateway = null) {
		$this->_gateway = $gateway;
		
		$this->_unique_id = md5(time() . self::$UNIQUE_ID_SALT . rand());
	}
	
	/**
	 * Accessor.
	 * 
	 * Set the body text of the message
	 *
	 * @param string $text The body text of the message
	 * @param bool $unicode Flag indicating that the body text is Unicode encoded
	 * 
	 * @todo Validate the values passed in parameter. (too long ?)
	 */
	public function setText($text, $unicode = null) {
		$this->_text = $text;
		if (is_bool($unicode)) {
			$this->_unicode = $unicode;
		}
	}
	
	/**
	 * Accessor.
	 * 
	 * Get the body text of the message.
	 *
	 * @return string
	 */
	public function getText() {
		return $this->_text;
	}
	
	/**
	 * Indicates if the message is Unicode encoded.
	 *
	 * @return bool
	 */
	public function isUnicode() {
		return $this->_unicode;
	}
	
	/**
	 * Accessor.
	 * 
	 * Set the destination of the message. Must be a string filled with a 
	 * numeric value.
	 *
	 * @param string $to
	 */
	public function setTo($to) {
		$this->_to = $to;
	}
	
	/**
	 * Accessor.
	 * 
	 * Get the destionation of the message.
	 *
	 * @return string
	 */
	public function getTo() {
		return $this->_to;
	}
	
	/**
	 * Accessor.
	 * 
	 * Set the origin of the message. 
	 * 
	 * Some gateway accept alphanumeric value but they cant assure you that it 
	 * will be accepted at the destination. 
	 * 
	 * With Clickatell, you can set a required features that will make sure 
	 * that the destination gateway will accept your "from" value.
	 *
	 * @param string $from
	 */
	public function setFrom($from) {
		$this->_from = $from;
	}
	
	/**
	 * Accessor.
	 * 
	 * Get the origin of the message.
	 *
	 * @return string
	 */
	public function getFrom() {
		return $this->_from;
	}
	
	/**
	 * Get the unique id of the message generated at the creation time.
	 *
	 * @return string
	 */
	public function getUID() {
		return $this->_unique_id;
	}
	
	/**
	 * Send the message to the gateway.
	 * 
	 * You can specify another gateway to this method. If so, this gateway will
	 * be used over the one specified in the constructor.
	 * 
	 * The return of this method is an array indicating the message id 
	 * generated by the server and the destination of the message.
	 * ex.:
	 * <code>
	 * array(
	 * 	'to' => '123456', 
	 * 	'apimsgid' => 'asbreidu8gfd656fds'
	 * )
	 * </code>
	 *
	 * @param array $send_options Options to use by the gateway. These options are described in the gateway class.
	 * @param Cameo_SMS_Gateway_Abstract $gateway (optional) Gateway to use for sending this message.
	 * @return array An array that indicates the id given by the server and the destination.
	 * 
	 * @throws Cameo_SMS_Exception When no gateway was specified
	 * 
	 * @todo validates the values (is the text, destination and source are present ?)
	 */
	public function send(array $send_options = array(), Cameo_SMS_Gateway_Abstract $gateway = null) {
		if (!($gateway = $this->_getGateway($gateway))) {
			throw new Cameo_SMS_Exception('Cannot send the message, no gateway provided.');
		}
		
		return $gateway->send($this, $send_options);
	}
	
	/**
	 * Send the message to the gateway to a list of person.
	 * 
	 * It's recommended to use this method to send a batch of message because
	 * some gateway have special mechanism for this sort of task.
	 * 
	 * The return of this method is an array of array indicating the message id 
	 * generated by the server and the destination of the message.
	 * ex.:
	 * <code>
	 * array(
	 * 	array(
	 * 		'to' => '123456', 
	 * 		'apimsgid' => 'asbreidu8gfd656fds'
	 * 	),
	 * 	array(
	 * 		'to' => '23456', 
	 * 		'apimsgid' => 'g6dfs789g6s6re78wr'
	 * 	)
	 * )
	 * </code>
	 *
	 * @param array $values List of destinations for the message
	 * @param array $send_options Options to use by the gateway. These options are described in the gateway class.
	 * @param Cameo_SMS_Gateway_Abstract $gateway (optional) Gateway to use for sending this message.
	 * @return array An array of array that indicates the id given by the server for each destination.
	 * 
	 * @throws Cameo_SMS_Exception When no gateway was specified
	 */
	public function batch(array $values, array $send_options = array(), Cameo_SMS_Gateway_Abstract $gateway = null) {
		if (!($gateway = $this->_getGateway($gateway))) {
			throw new Cameo_SMS_Exception('Cannot send the message, no gateway provided.');
		}
		
		return $gateway->batch($this, $values, $send_options);
	}
	
	/**
	 * Utility method that select the gateway to use.
	 * 
	 * Gets the gateway in passed in parameter if not null or the gateway setted
	 * by the constructed. If these two doesn't are null, return false.
	 *
	 * @param Cameo_SMS_Gateway_Abstract $gateway (optional) Gateway to use preferably
	 * @return Cameo_SMS_Gateway_Abstract The gateway to use or false.
	 */
	private function _getGateway(Cameo_SMS_Gateway_Abstract $gateway = null) {
		if (!is_null($gateway)) {
			return $gateway;
		} else	if (!is_null($this->_gateway)) {
			return $this->_gateway;
		}
		
		return false;
	}
	
}